<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="../Universal.css">
</head>
<body>
    
    <div id="cnblogs_post_body" class="blogpost-body">
        <h1>正则表达式</h1>
    <p>正则表达式（英语：Regular Expression，在代码中常简写为regex）。正则表达式是一个字符串，使用单个字符串来描述、用来定义匹配规则，匹配一系列符合某个句法规则的字符串。在开发中，正则表达式通常被用来检索、替换那些符合某个规则的文本。</p>
    <h3>正则表达式的匹配规则</h3>
    <p>参照帮助文档，在Pattern类中有正则表达式的的规则定义，正则表达式中明确区分大小写字母。我们来学习语法规则。</p>
    <p>正则表达式的语法规则：</p>
    <div class="cnblogs_code">
    <pre><span style="color: rgba(0, 0, 0, 1)">字符：x
    含义：代表的是字符x
    例如：匹配规则为 </span>"a"，那么需要匹配的字符串内容就是 ”a”</pre>
    </div>
    <div class="cnblogs_code">
    <pre><span style="color: rgba(0, 0, 0, 1)">字符：\\
    含义：代表的是反斜线字符</span>'\'<span style="color: rgba(0, 0, 0, 1)">
    例如：匹配规则为</span>"\\" ，那么需要匹配的字符串内容就是 ”\”</pre>
    </div>
    <div class="cnblogs_code">
    <pre><span style="color: rgba(0, 0, 0, 1)">字符：\t
    含义：制表符
    例如：匹配规则为</span>"\t" ，那么对应的效果就是产生一个制表符的空间</pre>
    </div>
    <div class="cnblogs_code">
    <pre><span style="color: rgba(0, 0, 0, 1)">字符：\n
    含义：换行符
    例如：匹配规则为</span>"\n"，那么对应的效果就是换行,光标在原有位置的下一行</pre>
    </div>
    <div class="cnblogs_code">
    <pre><span style="color: rgba(0, 0, 0, 1)">字符：\r
    含义：回车符
    例如：匹配规则为</span>"\r" ，那么对应的效果就是回车后的效果,光标来到下一行行首</pre>
    </div>
    <div class="cnblogs_code">
    <pre><span style="color: rgba(0, 0, 0, 1)">字符类：[abc]
    含义：代表的是字符a、b 或 c
    例如：匹配规则为</span>"[abc]" ，那么需要匹配的内容就是字符a，或者字符b，或字符c的一个</pre>
    </div>
    <div class="cnblogs_code">
    <pre>字符类：[^<span style="color: rgba(0, 0, 0, 1)">abc]
    含义：代表的是除了 a、b 或 c以外的任何字符
    例如：匹配规则为</span>"[^abc]"，那么需要匹配的内容就是不是字符a，或者不是字符b，或不是字符c的任意一个字符</pre>
    </div>
    <div class="cnblogs_code">
    <pre>字符类：[a-zA-<span style="color: rgba(0, 0, 0, 1)">Z]
    含义：代表的是a 到 z 或 A 到 Z，两头的字母包括在内
    例如：匹配规则为</span>"[a-zA-Z]"，那么需要匹配的是一个大写或者小写字母</pre>
    </div>
    <div class="cnblogs_code">
    <pre>字符类：[0-9<span style="color: rgba(0, 0, 0, 1)">]
    含义：代表的是 0到9数字，两头的数字包括在内
    例如：匹配规则为</span>"[0-9]"，那么需要匹配的是一个数字</pre>
    </div>
    <div class="cnblogs_code">
    <pre>字符类：[a-zA-Z_0-9<span style="color: rgba(0, 0, 0, 1)">]
    含义：代表的字母或者数字或者下划线(即单词字符)
    例如：匹配规则为</span>" [a-zA-Z_0-9] "，那么需要匹配的是一个字母或者是一个数字或一个下滑线</pre>
    </div>
    <div class="cnblogs_code">
    <pre><span style="color: rgba(0, 0, 0, 1)">预定义字符类：.
    含义：代表的是任何字符
    例如：匹配规则为</span>" . "，那么需要匹配的是一个任意字符。如果，就想使用 . 的话，使用匹配规则"\\."来实现</pre>
    </div>
    <div class="cnblogs_code">
    <pre><span style="color: rgba(0, 0, 0, 1)">预定义字符类：\d
    含义：代表的是 0到9数字，两头的数字包括在内，相当于[</span>0-9<span style="color: rgba(0, 0, 0, 1)">]
    例如：匹配规则为</span>"\d "，那么需要匹配的是一个数字</pre>
    </div>
    <div class="cnblogs_code">
    <pre><span style="color: rgba(0, 0, 0, 1)">预定义字符类：\w
    含义：代表的字母或者数字或者下划线(即单词字符)，相当于[a</span>-zA-Z_0-9<span style="color: rgba(0, 0, 0, 1)">]
    例如：匹配规则为</span>"\w "，，那么需要匹配的是一个字母或者是一个数字或一个下滑线</pre>
    </div>
    <div class="cnblogs_code">
    <pre>边界匹配器：^<span style="color: rgba(0, 0, 0, 1)">
    含义：代表的是行的开头
    例如：匹配规则为</span>^[abc][0-9]$ ，那么需要匹配的内容从[abc]这个位置开始, 相当于左双引号</pre>
    </div>
    <div class="cnblogs_code">
    <pre><span style="color: rgba(0, 0, 0, 1)">边界匹配器：$
    含义：代表的是行的结尾
    例如：匹配规则为</span>^[abc][0-9]$ ，那么需要匹配的内容以[0-9]这个结束, 相当于右双引号</pre>
    </div>
    <div class="cnblogs_code">
    <pre><span style="color: rgba(0, 0, 0, 1)">边界匹配器：\b
    含义：代表的是单词边界
    例如：匹配规则为</span>"\b[abc]\b" ，那么代表的是字母a或b或c的左右两边需要的是非单词字符([a-zA-Z_0-9])</pre>
    </div>
    <div class="cnblogs_code">
    <pre>数量词：X?<span style="color: rgba(0, 0, 0, 1)">
    含义：代表的是X出现一次或一次也没有
    例如：匹配规则为</span>"a?"，那么需要匹配的内容是一个字符a，或者一个a都没有</pre>
    </div>
    <div class="cnblogs_code">
    <pre>数量词：X*<span style="color: rgba(0, 0, 0, 1)">
    含义：代表的是X出现零次或多次
    例如：匹配规则为</span>"a*" ，那么需要匹配的内容是多个字符a，或者一个a都没有</pre>
    </div>
    <div class="cnblogs_code">
    <pre>数量词：X+<span style="color: rgba(0, 0, 0, 1)">
    含义：代表的是X出现一次或多次
    例如：匹配规则为</span>"a+"，那么需要匹配的内容是多个字符a，或者一个a</pre>
    </div>
    <div class="cnblogs_code">
    <pre><span style="color: rgba(0, 0, 0, 1)">数量词：X{n}
    含义：代表的是X出现恰好 n 次
    例如：匹配规则为</span>"a{5}"，那么需要匹配的内容是5个字符a</pre>
    </div>
    <div class="cnblogs_code">
    <pre><span style="color: rgba(0, 0, 0, 1)">数量词：X{n,}
    含义：代表的是X出现至少 n 次
    例如：匹配规则为</span>"a{5, }"，那么需要匹配的内容是最少有5个字符a</pre>
    </div>
    <div class="cnblogs_code">
    <pre><span style="color: rgba(0, 0, 0, 1)">数量词：X{n,m}
    含义：代表的是X出现至少 n 次，但是不超过 m 次
    例如：匹配规则为</span>"a{5,8}"，那么需要匹配的内容是有5个字符a 到 8个字符a之间</pre>
    </div>
    <h3>正则表达式规则匹配练习</h3>
    <p>请写出满足如下匹配规则的字符串:</p>
    <p>规则："[0-9]{6,12}"</p>
    <p>该规则需要匹配的内容是：长度为6位到12位的数字。如：使用数据"123456789"进行匹配结果为true；使用数据"12345"进行匹配结果为false。</p>
    <p>&nbsp;</p>
    <p>规则："1[34578][0-9]{9}"</p>
    <p>该规则需要匹配的内容是：11位的手机号码，第1位为1，第2位为3、4、5、7、8中的一个，后面9位为0到9之间的任意数字。</p>
    <p>如：使用数据"12345678901"进行匹配结果为false；使用数据"13312345678"进行匹配结果为true。</p>
    <p>&nbsp;</p>
    <p>规则："a*b"</p>
    <p>该规则需要匹配的内容是：在多个a或零个a后面有个b；b必须为最后一个字符。</p>
    <p>如：使用数据"aaaaab"进行匹配结果为true；使用数据"abc"进行匹配结果为false。</p>
    <h3>字符串类中涉及正则表达式的常用方法</h3>
    <p>public boolean matches(String regex) //判断字符串是否匹配给定的规则</p>
    <p>举例：校验qq号码.</p>
    <p>1: 要求必须是5-15位数字</p>
    <p>2: 0不能开头</p>
    <p>代码演示：</p>
    <div class="cnblogs_code">
    <pre>String qq = "604154942"<span style="color: rgba(0, 0, 0, 1)">;
    String regex </span>= "[1-9][0-9]{4,14}"<span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">boolean</span> flag2 = qq.matches(regex);</pre>
    </div>
    <p>举例：校验手机号码</p>
    <p>1：要求为11位数字</p>
    <p>2：第1位为1，第2位为3、4、5、7、8中的一个，后面9位为0到9之间的任意数字。</p>
    <p>代码演示：</p>
    <div class="cnblogs_code">
    <pre>String phone = "18800022116"<span style="color: rgba(0, 0, 0, 1)">;
    String regex </span>= "1[34578][0-9]{9}"<span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">boolean</span> flag = phone.matches(regex);</pre>
    </div>
    <p>public String[] split(String regex) //根据给定正则表达式的匹配规则，拆分此字符串</p>
    <p>举例：分割出字符串中的的数字</p>
    <div class="cnblogs_code">
    <pre>代码演示：<br>String s = "18-22-40-65"<span style="color: rgba(0, 0, 0, 1)">;
    String regex </span>= "-"<span style="color: rgba(0, 0, 0, 1)">;
    String[] result </span>=<span style="color: rgba(0, 0, 0, 1)"> s.split(regex);
    
    代码演示：
    String s </span>= "18 22 40 65"<span style="color: rgba(0, 0, 0, 1)">;
    String regex </span>= " "<span style="color: rgba(0, 0, 0, 1)">;
    String[] result </span>= s.split(regex);</pre>
    </div>
    <p>public String replaceAll(String regex,String replacement)//将符合规则的字符串内容，全部替换为新字符串</p>
    <p>举例：把文字中的数字替换成*</p>
    <p>代码演示：</p>
    <div class="cnblogs_code">
    <pre>String s = "Hello12345World6789012"<span style="color: rgba(0, 0, 0, 1)">;
    String regex </span>= "[0-9]"<span style="color: rgba(0, 0, 0, 1)">;
    String result </span>= s.replaceAll(regex, "*");</pre>
    </div>
    <h3>正则表达式练习</h3>
    <p>匹配正确的数字，匹配规则：</p>
    <p>匹配正整数：”\\d+”</p>
    <p>匹配正小数：”\\d+\\.\\d+” &nbsp;</p>
    <p>匹配负整数：”-\\d+”</p>
    <p>匹配负小数：”-\\d+\\.\\d+”</p>
    <p>匹配保留两位小数的正数：”\\d+\\.\\d{2}”</p>
    <p>匹配保留1-3位小数的正数：”\\d+\\.\\d{1,3}”</p>
    <p>匹配合法的邮箱，匹配规则：</p>
    <p>”[a-zA-Z_0-9]+@[a-zA-Z_0-9]+(\\.[a-zA-Z_0-9]+)+”</p>
    <p>”\\w+@\\w+(\\.\\w+)+”</p>
    <p>获取IP地址(192.168.1.100)中的每段数字，匹配规则：</p>
    <p>　　”\\.”</p>
    <h2>Date</h2>
    <p>类 Date 表示特定的瞬间，精确到毫秒。</p>
    <p>继续查阅Date类的描述，发现Date拥有多个构造函数，只是部分已经过时，但是其中有未过时的构造函数可以把毫秒值转成日期对象。</p>
    <div class="cnblogs_code">
    <pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">创建日期对象，把当前的毫秒值转成日期对象</span>
    Date date = <span style="color: rgba(0, 0, 255, 1)">new</span> Date(1607616000000L<span style="color: rgba(0, 0, 0, 1)">);
    System.out.println(date);
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">打印结果：Fri Dec 11 00:00:00 CST 2020</span></pre>
    </div>
    <p>可是将毫秒值转成日期后，输出的格式不利于我们阅读，继续查阅API，Date中有getYear、getMouth等方法，可以他们已经过时，继续往下查阅，看到了toString方法。</p>
    <p>点开toString()方法查阅，原来上面打印的date对象就是默认调用了这个toString方法，并且在这个方法下面还有让我们参见toLocaleString方法，点进去，这个方法又过时了，从 JDK 1.1 开始，由 DateFormat.format(Date date) 取代。既然这个方法被DateFormat.format(Date date) 取代，那么就要去查阅DateFormat类。</p>
    <h3>Date类常用方法</h3>
    <p>把日期对象转换成对应的时间毫秒值</p>
    <div class="cnblogs_code">
    <pre>  Date date = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Date();
      l</span>=<span style="color: rgba(0, 0, 0, 1)">date.getTime();
      System.out.println(l);</span></pre>
    </div>
    <p>毫秒的0点,时间原点; 公元1970年1月1日,午夜0:00:00 英国格林威治 &nbsp;毫秒值就是0</p>
    <p>System.currentTimeMillis() 返回值long类型参数，用于获取当前日期的毫秒值 ，必须依赖毫秒值</p>
    <h2>DateFormat</h2>
    <p>DateFormat 是日期/时间格式化子类的抽象类，它以与语言无关的方式格式化并解析日期或时间。日期/时间格式化子类（如 SimpleDateFormat类）允许进行格式化（也就是日期 -&gt; 文本）、解析（文本-&gt; 日期）和标准化。</p>
    <p>我们通过这个类可以帮我们完成日期和文本之间的转换。</p>
    <p>继续阅读API，DateFormat 可帮助进行格式化并解析任何语言环境的日期。对于月、星期，甚至日历格式（阴历和阳历），其代码可完全与语言环境的约定无关。</p>
    <h3>日期格式</h3>
    <p>要格式化一个当前语言环境下的日期也就是日期 -&gt; 文本），要通过下面的方法来完成。DateFormat是抽象类，我们需要使用其子类SimpleDateFormat来创建对象。</p>
    <p>构造方法</p>
    <p><img src="https://images2015.cnblogs.com/blog/612774/201707/612774-20170713183109415-1487068435.png" alt=""></p>
    <p>DateFormat类方法</p>
    <p>&nbsp;<img src="https://images2015.cnblogs.com/blog/612774/201707/612774-20170713183119728-1283050472.png" alt=""></p>
    <p>代码演示：</p>
    <div class="cnblogs_code">
    <pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">创建日期格式化对象,在获取格式化对象时可以指定风格</span>
    DateFormat df= <span style="color: rgba(0, 0, 255, 1)">new</span> SimpleDateFormat("yyyy-MM-dd");<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">对日期进行格式化</span>
    Date date = <span style="color: rgba(0, 0, 255, 1)">new</span> Date(1607616000000L<span style="color: rgba(0, 0, 0, 1)">);
    String str_time </span>=<span style="color: rgba(0, 0, 0, 1)"> df.format(date);
    System.out.println(str_time);</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">2020年12月11日</span></pre>
    </div>
    <p>DateFormat类的作用：即可以将一个Date对象转换为一个符合指定格式的字符串，也可以将一个符合指定格式的字符串转为一个Date对象。</p>
    <p>指定格式的具体规则我们可参照SimpleDateFormat类的说明，这里做简单介绍，规则是在一个字符串中，会将以下字母替换成对应时间组成部分，剩余内容原样输出：</p>
    <ul>
    <li>当出现y时，会将y替换成年</li>
    <li>当出现M时，会将M替换成月</li>
    <li>当出现d时，会将d替换成日</li>
    <li>当出现H时，会将H替换成时</li>
    <li>当出现m时，会将m替换成分</li>
    <li>当出现s时，会将s替换成秒</li>
    </ul>
    <h3>DateFormat类常用方法</h3>
    <p>format方法，用来将Date对象转换成String</p>
    <p>parse方法，用来将String转换成Date（转换时，该String要符合指定格式，否则不能转换）。</p>
    <p>代码演示：</p>
    <p>练习一：把Date对象转换成String</p>
    <div class="cnblogs_code">
    <pre>Date date = <span style="color: rgba(0, 0, 255, 1)">new</span> Date(1607616000000L);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">Fri Dec 11 00:00:00 CST 2020</span>
    DateFormat df = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> SimpleDateFormat(“yyyy年MM月dd日”);
    String str </span>=<span style="color: rgba(0, 0, 0, 1)"> df.format(date);
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">str中的内容为2020年12月11日</span></pre>
    </div>
    <p>练习二：把String转换成Date对象</p>
    <div class="cnblogs_code">
    <pre>String str =<span style="color: rgba(0, 0, 0, 1)"> ”2020年12月11日”;
    DateFormat df </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> SimpleDateFormat(“yyyy年MM月dd日”);
    Date date </span>=<span style="color: rgba(0, 0, 0, 1)"> df.parse( str );
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">Date对象中的内容为Fri Dec 11 00:00:00 CST 2020</span></pre>
    </div>
    <h2>Calendar</h2>
    <p>Calendar是日历类，在Date后出现，替换掉了许多Date的方法。该类将所有可能用到的时间信息封装为静态成员变量，方便获取。</p>
    <p>Calendar为抽象类，由于语言敏感性，Calendar类在创建对象时并非直接创建，而是通过静态方法创建，将语言敏感内容处理好，再返回子类对象，如下：</p>
    <h3>Calendar类静态方法</h3>
    <p>Calendar c = Calendar.getInstance(); &nbsp;//返回当前时间</p>
    <h3><span style="line-height: 1.5">Calendar类常用方法</span></h3>
    <p><span style="line-height: 1.5">public static Calendar getInstance() //获取日期对象</span></p>
    <p>public int get(int field)//获取时间字段值，字段参见帮助文档</p>
    <p>YEAR 年</p>
    <p>MONTH 月，从0开始算起，最大11；0代表1月，11代表12月。</p>
    <p>DATE 天</p>
    <p>HOUR 时</p>
    <p>MINUTE分</p>
    <p>SECOND秒</p>
    <p>代码演示：</p>
    <div class="cnblogs_code">
    <pre>Calendar c =<span style="color: rgba(0, 0, 0, 1)"> Calendar.getInstance();
    </span><span style="color: rgba(0, 0, 255, 1)">int</span> year = c.<span style="color: rgba(0, 0, 255, 1)">get</span>(Calendar.YEAR);</pre>
    </div>
    <p><span style="line-height: 1.5">public void add(int field,int amount)//指定字段增加某值</span></p>
    <p>代码演示：</p>
    <div class="cnblogs_code">
    <pre>Calendar c =<span style="color: rgba(0, 0, 0, 1)"> Calendar.getInstance();
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">修改当前时间为3天后</span><span style="color: rgba(0, 0, 0, 1)">
    c.add(Calendar.DATE, </span><span style="color: rgba(128, 0, 128, 1)">3</span><span style="color: rgba(0, 0, 0, 1)">);
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">修改当前时间为5小时后</span><span style="color: rgba(0, 0, 0, 1)">
    c.add(Calendar.HOUR, </span><span style="color: rgba(128, 0, 128, 1)">5</span>);</pre>
    </div>
    <p><span style="line-height: 1.5">public final void set(int field,int value)//设置指定字段的值</span></p>
    <p>代码演示：</p>
    <div class="cnblogs_code">
    <pre>Calendar c =<span style="color: rgba(0, 0, 0, 1)"> Calendar.getInstance();
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">设置时间为2020年5月20日</span><span style="color: rgba(0, 0, 0, 1)">
    c.</span><span style="color: rgba(0, 0, 255, 1)">set</span>(Calendar.YEAR, <span style="color: rgba(128, 0, 128, 1)">2020</span><span style="color: rgba(0, 0, 0, 1)">);
    c.</span><span style="color: rgba(0, 0, 255, 1)">set</span>(Calendar.MONTH, <span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)">);
    c.</span><span style="color: rgba(0, 0, 255, 1)">set</span>(Calendar.DATE, <span style="color: rgba(128, 0, 128, 1)">20</span>);</pre>
    </div>
    <p><span style="line-height: 1.5">public final Date getTime()//获取该日历对象转成的日期对象</span></p>
    <p>代码演示：</p>
    <div class="cnblogs_code">
    <pre>Calendar c =<span style="color: rgba(0, 0, 0, 1)"> Calendar.getInstance();
    Date d </span>= c.getTime();</pre>
    </div>
    <p><span style="line-height: 1.5">注意事项</span></p>
    <ul>
    <li>西方星期的开始为周日，中国为周一。</li>
    <li>在Calendar类中，月份的表示是以0-11代表1-12月。</li>
    <li>日期是有大小关系的，时间靠后，时间越大。</li>
    </ul>
    <h3>日期相关类练习</h3>
    <p>求出自己已经出生多少天</p>
    <p><span style="line-height: 1.5">代码实现：</span></p>
    <div class="cnblogs_code">
    <pre>public static void main(String[] args) {<br>    Calendar my = Calendar.getInstance();<br>    //设置出生年月日 1995-05-10<br>    my.set(Calendar.YEAR, 1995);<br>    my.set(Calendar.MONTH, 4);<br>    my.set(Calendar.DATE, 10);<br>    //计算天数<br>    long day =(System.currentTimeMillis()-my.getTimeInMillis())/(24*60*60*1000L);<br>    System.out.println(day);<br>}</pre>
    </div>
    </div>

</body>
</html>